package com.appkubes.fintech.admin.application.risk.rule.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.appkubes.fintech.admin.application.data.contact.dao.DataContactDao;
import com.appkubes.fintech.admin.application.risk.data.boole.service.BooleRiskService;
import com.appkubes.fintech.admin.application.risk.rule.dao.RiskRuleDao;
import com.appkubes.fintech.admin.application.risk.rule.entity.dto.RiskResultDTO;
import com.appkubes.fintech.admin.application.risk.rule.entity.vo.MallBaiRongVO;
import com.appkubes.fintech.admin.application.risk.rule.service.RiskService;
import com.appkubes.fintech.admin.application.user.dao.UserBaseInfoDao;
import com.appkubes.fintech.admin.application.user.dao.UserJobDao;
import com.appkubes.fintech.admin.task.job.BaiRongTiming;
import com.appkubes.fintech.core.po.FintechRiskXingpangWithBLOBs;
import com.appkubes.fintech.core.po.FintechUserBaseInfo;
import com.appkubes.fintech.core.po.FintechUserJob;
import com.br.client.facade.MerchantServer;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author: Rongjie
 * @Date: 2020/3/15
 * @Description:
 */
@Service
@Slf4j
public class RiskServiceImpl implements RiskService {

    private int ResultCode_accept = 0;
    private int ResultCode_reject = 1;

    @Autowired
    UserBaseInfoDao userBaseInfoDao;
    @Autowired
    RiskRuleDao riskRuleDao;

    @Autowired
    UserJobDao userJobDao;
    @Autowired(required = false)
    RestTemplate restTemplate;


    @Autowired
    DataContactDao dataContactDao;

    @Resource
    BooleRiskService booleRiskService;

    @Override
    public List<RiskResultDTO> getResult(String userKey) {
        List<RiskResultDTO> list = new ArrayList<RiskResultDTO>();
        FintechUserBaseInfo userBaseInfo = userBaseInfoDao.selectByPrimaryKey(userKey);
        if (userBaseInfo == null) {
            list.add(new RiskResultDTO(ResultCode_reject,"系统错误","获取不到用户信息"));
            return list;
        }

        //1,年龄准入规则设置
        if (userBaseInfo.getAge()<22 || userBaseInfo.getAge()>42) {
            list.add(new RiskResultDTO(ResultCode_reject,"年龄准入规则","年龄："+userBaseInfo.getAge()));
        }

        //3,户籍禁入规则设置
        String[] reg = {
                "630","632",
                "350","352",
                "540","542",
                "650","652","653","654","659",
                "130","131",
                "520","522",
                "210","211",
                "620","621","622","623",
                "640","642",
                "150","152",
                "370","371","372",
                "140","142",
                "410","411","412",
                "45"
        };
        for (String str:reg) {
            if(userBaseInfo.getIdentityNum().startsWith(str)) {
                list.add(new RiskResultDTO(ResultCode_reject,"户籍禁入规则","命中:"+userBaseInfo.getIdentityNum()));
                break;
            }
        }

        //4,单位地址省份禁入规则设置
        FintechUserJob fintechUserJob = userJobDao.selectByPrimaryKey(userKey);
        if (fintechUserJob == null) {
            list.add(new RiskResultDTO(ResultCode_reject,"系统错误","获取不到用户工作信息"));
            return list;
        }
        String[] provs = {"青海省","西藏自治区","新疆维吾尔自治区","宁夏回族自治区","内蒙古自治区","广西"};
        for (String str:provs) {
            if(fintechUserJob.getEmployerProvince().contains(str)) {
                list.add(new RiskResultDTO(ResultCode_reject,"单位地址省份禁入规则","命中:"+fintechUserJob.getEmployerProvince()));
                break;
            }
        }

        //5,家庭地址省份禁入规则设置
        for (String str:provs) {
            if(userBaseInfo.getLivingProvince().contains(str)) {
                list.add(new RiskResultDTO(ResultCode_reject,"家庭地址省份禁入规则","命中:"+userBaseInfo.getLivingProvince()));
                break;
            }
        }

        //6,单位职位信息规则设置
        String[] jobsList = {
                "侦探、地下钱庄、赌博、传销、摆摊、",
                "夜总会、桑拿、按摩、卡拉OK、歌舞厅、足浴保健、足浴、足道养生、洗浴、水疗、养生保健、球馆、休闲会所、休闲、游戏中心、健身馆、健身、网咖、网吧、网络会所、club",
                "清洁、食堂、家政、保姆、维修、外卖",
                "建筑、装修、检修、送货、搬运",
                "出租、公交",
                "军区、警备区、卫戍区",
                "寺庙、道馆、佛教协会、道教协会、教堂、天主教、基督教、伊斯兰教、清真寺",
                "保安、消防、武警、大队、特警",
                "无业、自由职业、作家、画家、歌手、家庭主妇、无固定工作、小区、工作室"
        };
        for (String str:jobsList) {
            String[] jobs = str.split("、");
            for (String job:jobs) {
                if(fintechUserJob.getEmployer().contains(str)) {
                    list.add(new RiskResultDTO(ResultCode_reject,"单位职位信息规则","命中:"+fintechUserJob.getEmployer()));
                    break;
                }
            }

        }

        //7,通讯录准入设置
//        int contactCount = dataContactDao.selectCount(userKey);
//        if (contactCount<30) {
//            list.add(new RiskResultDTO(ResultCode_reject,"通讯录准入设置","通讯录数量："+contactCount));
//        }

        //8,运营商实名准入
        String[] names = {"不匹配","部分匹配","未能"};
        FintechRiskXingpangWithBLOBs riskXingpangWithBLOBs =null;// riskXingPanDao.selectByPrimaryKey(userKey);
        if(riskXingpangWithBLOBs == null || riskXingpangWithBLOBs.getOperatorreportresult() == null) {
            list.add(new RiskResultDTO(ResultCode_reject,"数据异常","获取不到星盘运营商通话报告"));
        }
        else {
            String result = riskXingpangWithBLOBs.getOperatorreportresult();
            JSONObject jsonObject = JSON.parseObject(result).getJSONObject("data");
            String name_matching = ((JSONObject)jsonObject.getJSONArray("sensitive_info").get(0)).getJSONObject("result_detail_info").getString("name_matching");
            for (String str:names) {
                if (name_matching.contains(str)) {
                    list.add(new RiskResultDTO(ResultCode_reject,"运营商实名准入",name_matching));
                }
            }

            //9,运营商在网时长  "10个月"
            JSONObject object= jsonObject.getJSONObject("operator_info");
            String registration_history="";
            if(object!=null) {
                registration_history = object.getString("registration_history");
            }
            if (StringUtils.isNotBlank(registration_history)&& !registration_history.contains("年")) {
                if (registration_history.contains("月")) {
                    String monthStr = registration_history.substring(0,registration_history.indexOf("个"));
                    int month = Integer.parseInt(monthStr);
                    if (month<12) {
                        list.add(new RiskResultDTO(ResultCode_reject,"运营商在网时长" , registration_history));
                    }
                }
            }

            //10,运营商通讯记录  "2020-02-28T10:51:28.000"
            String the_last_call_time = jsonObject.getJSONObject("communication_detection").getString("the_last_call_time");
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
                long lastTime = userBaseInfo.getCreateTime().getTime() - sdf.parse(the_last_call_time).getTime();
                if (lastTime>15*24*360000) {
                    list.add(new RiskResultDTO(ResultCode_reject,"运营商通讯记录","最近通话时间:"+the_last_call_time));
                }
            }
            catch (ParseException e) {
                log.error("运营商通讯记录 时间解析出错："+the_last_call_time);
            }

            //11,运营商通讯检查   2019-02-07 19:04:48 静默1天16小时
            String the_last_silent_duration_time = jsonObject.getJSONObject("communication_detection").getString("the_last_silent_duration_time");
            if (the_last_silent_duration_time == null) {
                list.add(new RiskResultDTO(ResultCode_reject,"运营商通讯检查","静默时长数据缺失"));
            }
            else  {
                String timeStr = the_last_silent_duration_time.substring(0,the_last_silent_duration_time.lastIndexOf(" "));
                try {
                    String silentStr = the_last_silent_duration_time.substring(the_last_silent_duration_time.lastIndexOf(" "),the_last_silent_duration_time.length());
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    long disTime = Calendar.getInstance().getTimeInMillis() - sdf.parse(timeStr).getTime();
                    if (disTime > 3*24*3600 && (!silentStr.contains("天") || !silentStr.contains("月"))) {
                        list.add(new RiskResultDTO(ResultCode_reject,"运营商通讯检查","最近一次静默时长："+the_last_silent_duration_time));
                    }
                }
                catch (ParseException e) {
                    log.error("运营商通讯检查 时间解析出错："+the_last_call_time);
                }
            }

            //12,运营商通讯记录总数检查
            int phone_count = jsonObject.getJSONObject("social_connectionsInfo").getInteger("phone_count");
            if (phone_count <=0)
                list.add(new RiskResultDTO(ResultCode_reject,"运营商通讯记录总数检查","数量："+phone_count));

            //13,运营商社交关系检查
            int interflow_call_phone_count = jsonObject.getJSONObject("social_connectionsInfo").getInteger("interflow_call_phone_count");
            if (interflow_call_phone_count <=0)
                list.add(new RiskResultDTO(ResultCode_reject,"运营商社交关系检查","数量："+interflow_call_phone_count));

        }

        //布尔风控
        String boolStr = booleRiskService.getPreRiskStr(userKey);
        if (boolStr == null || boolStr.equals("")) {
            list.add(new RiskResultDTO(ResultCode_reject,"布尔前置数据异常","获取不到数据"));
        }
        else {
            JSONObject boolJson = JSON.parseObject(boolStr).getJSONObject("resp_data");

            //14 特殊关注名单检查
            String risk_black = boolJson.getJSONObject("risk_list_check").getString("risk_black");
            if (risk_black.contains("命中") && !risk_black.contains("未命中")) {
                list.add(new RiskResultDTO(ResultCode_reject,"特殊关注名单检查",risk_black));
            }

            //17 评分模型
            int grade = boolJson.getInteger("grade");
            if (grade >=80) {
                list.add(new RiskResultDTO(ResultCode_reject,"评分模型","布尔评分："+grade));
            }
        }

        String boolReportStr = booleRiskService.getProphetReportStr(userKey);
        if (boolReportStr == null || boolReportStr.equals("")) {
            list.add(new RiskResultDTO(ResultCode_reject,"布尔预言家报告数据异常","获取不到数据"));
        }
        else {
            JSONObject boolJson = JSON.parseObject(boolReportStr).getJSONObject("resp_data");

            //15 逾期信息检查
            String is_overdue = boolJson.getJSONObject("overdue_info").getString("is_overdue");
            if (!is_overdue.equals("") && !is_overdue.equals("0")) {
                list.add(new RiskResultDTO(ResultCode_reject,"逾期信息检查","逾期结果："+is_overdue));
            }

            //16 当前逾期信息检查
            String settlement = boolJson.getJSONObject("overdue_info").getString("settlement");
            if (!settlement.equals("") && !settlement.equals("0")) {
                list.add(new RiskResultDTO(ResultCode_reject,"当前逾期信息检查","逾期结果："+settlement));
            }
        }

        return list;
    }
    /**
     * 定时更新token
     * @return
     */
    @Override
    public String BaiRongTiming() {
        RestTemplate restTemplate = new RestTemplate();
        //第一种 postForEntity 可以获取响应状态，头部信息等
        String url = "https://apiservice.100credit.com/api/auth-service/auth/getToken?username=fenfStr&password=fenfStr123";
        ResponseEntity<String> entity = restTemplate.postForEntity(url,"",String.class);
        String str = entity.getBody();
        System.err.println(str+"执行静态定时任务时间: " + new Date());
        String st= JsonPath.read(str, "@.data");
        return st;
    }
    /**
     * 填写信息获取swit_number
     * @return
     */
    @Override
    public String StrategyDemoAppkey2(MallBaiRongVO mallBaiRongVO) {
        MerchantServer ms = new MerchantServer();
        net.sf.json.JSONObject jso = new net.sf.json.JSONObject();
        jso.put("apiName", "strategyApi");
        net.sf.json.JSONObject reqData = new net.sf.json.JSONObject();
        reqData.put("strategy_id", "STR0037570");
        reqData.put("id", mallBaiRongVO.getId());
        reqData.put("cell", mallBaiRongVO.getCell());
        reqData.put("name", mallBaiRongVO.getName());
        jso.put("reqData", reqData);
        //如果不传apicode和appkey则读取yml配置文件中的信息
        String apiData = ms.getApiData(jso.toString(), "3007099", "5a3bd822a9b4c6bd4c0e236786be3d025922c1976e905e97d3116eab48fd7b54");
        System.out.println(apiData);
        String st= JsonPath.read(apiData, "@.swit_number");
        System.out.println(st);
        return "st";
    }

    @Override
    public Integer InsertBaiRong(MallBaiRongVO mallBaiRongVO) {
        return riskRuleDao.InsertBaiRong(mallBaiRongVO);
    }
}
